package cn.com.cfae.iras.doc.analyze.components.consistency;

import cn.com.cfae.iras.doc.analyze.components.BaseComponent;
import cn.com.cfae.iras.doc.analyze.components.beans.ComponentResult;
import cn.com.cfae.iras.doc.analyze.keys.UnitType;
import cn.com.cfae.iras.doc.analyze.parse.kv.KVText;
import cn.com.cfae.iras.doc.analyze.parse.model.ChapterModel;
import cn.com.cfae.iras.doc.analyze.parse.model.DocumentModel;
import cn.com.cfae.iras.doc.analyze.parse.model.ExtractBizModel;
import cn.com.cfae.iras.doc.analyze.parse.model.ExtractItem;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by zouxun on 2018/10/29
 */
@Component("U1007")
@Scope("prototype")
public class U1007 extends BaseComponent {
    private static Logger logger = LoggerFactory.getLogger(U1007.class);

    @Autowired
    U1004 u1004;
    @Autowired
    U1005 u1005;

    /**
     * @desc 若财务风险内容处出现某会计科目，请与M-6中会计科目的数据做一致性检查。例如：财务风险中提示“存货占比较高风险”，
     * 并列示了三年及一期存货为A万元、B万元、C万元、D万元，则在M-6-1合并财务报表中，
     * 提取存货三年及一期的数据，核对是否一致（请注意单位是否一致，可能财务报表中单位是元、万元，而财务风险中提示万元、亿元）
     * @return
     */
    @Override
    public List<ComponentResult> handlerM() {
        logger.info("开始调用U1007组件，处理M表...............");
        DocumentModel documentModel = super.getExtractData();
        ChapterModel m2ChapterModel = documentModel.getChapterModel("M-2");
        ChapterModel m6ChapterModel = documentModel.getChapterModel("M-6");
        String m6CatalogId = "M-6";
        List<ComponentResult> componentResults = ruleCheck(m6CatalogId);
        return componentResults;
    }

    @Override
    public List<ComponentResult> handlerBM() {
        logger.info("开始调用U1007组件，处理BM表...............");
        String m6CatalogId = "BM-6";
        List<ComponentResult> componentResults = ruleCheck(m6CatalogId);
        return componentResults;
    }

    @Override
    public List<ComponentResult> handlerDM() {
        logger.info("开始调用U1007组件，处理DM表...............");
        String m6CatalogId = "DM-6";
        List<ComponentResult> componentResults = ruleCheck(m6CatalogId);
        return componentResults;
    }

    @Override
    public List<ComponentResult> handlerBDM() {
        logger.info("开始调用U1007组件，处理BDM表...............");
        String m6CatalogId = "BDM-6";
        List<ComponentResult> componentResults = ruleCheck(m6CatalogId);
        return componentResults;
    }

    private Map<String, Map<String, ExtractItem>> getTable(DocumentModel documentModel,String catalogId,String modelName){
        ChapterModel chapterModel = documentModel.getChapterModel(catalogId);
        if(chapterModel!=null){
            ExtractBizModel extractBizModel=chapterModel.getModel(modelName);
            if(extractBizModel!=null){
                Map<String, Map<String, ExtractItem>> map = extractBizModel.getTables();
                if(MapUtils.isNotEmpty(map)){
                    return map;
                }
            }
        }
        return null;
    }

    private KVText getTableKVTextValue(Map<String, ExtractItem> map,String key){
        if(MapUtils.isNotEmpty(map)){
            ExtractItem extractItem= map.get(key);
            if(extractItem!=null){
                return extractItem.getValue();
            }
        }
        return null;
    }

    private KVText getTableKVTextKey(Map<String, ExtractItem> map,String key){
        if(MapUtils.isNotEmpty(map)){
            ExtractItem extractItem= map.get(key);
            if(extractItem!=null){
                return extractItem.getKey();
            }
        }
        return null;
    }

    private String getAmount(String text){
        String amount= null;
        String regex = "(-{0,1}\\d{1,}\\.{0,1}\\d{1,})";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);

        while (matcher.find()) {
            amount=matcher.group(0);
        }
        return amount;
    }

    private String replaceComma(String text){
//        if(text.contains(",")){
//            text=text.replace(",","");
//        }
//        if(text.contains("，")){
//            text=text.replace("，","");
//        }
        return text.replaceAll("[,|，|(|)|（|）|。|\\s]{1,}","");
    }

    private List<ComponentResult> ruleCheck(String m6CatalogId){
        List<ComponentResult> componentResults = new ArrayList<>();
        String ruleName = getRuleTitle();

        DocumentModel documentModel = super.getExtractData();

        String[] tableNameMap = new String[]{"ZCFZ","LR","XJLL"};

        ChapterModel m2ChapterModel = documentModel.getChapterModel(getCatalogId());
        ChapterModel m6ChapterModel = documentModel.getChapterModel(m6CatalogId);

        try{
            if(m2ChapterModel!=null) {
                int blankCount = 0;
                //不一致
                int inconformityCount = 0;
                //一致
                int consistentCount = 0;
                //未识别或无法确定
                int unidentification=0;

                for (String tableName : tableNameMap) {
                    logger.info("当前处理模块：{}", tableName);
                    Map<String, Map<String, ExtractItem>> m2MapTable = getTable(documentModel, getCatalogId(), tableName);
                    Map<String, Map<String, ExtractItem>> m6MapTable = getTable(documentModel, m6CatalogId, tableName);

                    if (MapUtils.isNotEmpty(m2MapTable)) {
                        Set<String> m2Years = m2MapTable.keySet();

                            for (String m2Year : m2Years) {
                                Map<String, ExtractItem> map2 = m2MapTable.get(m2Year);

                                if (MapUtils.isNotEmpty(map2)) {
                                    Set<String> map2Keys = map2.keySet();

                                    for (String map2Key : map2Keys) {
                                        KVText map2KVTextValue = getTableKVTextValue(map2, map2Key);
                                        KVText map2KVTextKey = getTableKVTextKey(map2, map2Key);

                                        if (map2KVTextValue != null) {
                                            String map2ValueText = map2KVTextValue.getText();
                                            String map2KeyText = map2KVTextKey.getText();

                                            logger.info("==================================================================");
                                            logger.info("当前对比的会计科目：{}",map2KeyText);
                                            logger.info("年份：{}，M-2会计科目：{}，数值：{}", m2Year, map2KeyText, map2ValueText);

                                            String m2ItemName = getCatalogId().concat(map2KeyText);
                                            String m6ItemName = m6CatalogId.concat(map2KeyText);

                                            String keyword = "年份：".concat(m2Year).concat("，").concat(m2ItemName).concat("对比").concat(m6ItemName);
                                            logger.info("keyword：{}",keyword);

                                            ComponentResult componentResult = u1004.getComponentResult(getCatalogId(),getChapterId(),getRuleTitle(),keyword,"",true,getRegulationId(),m2ChapterModel.getStartPage(),null,"03");

                                            componentResult=u1005.setTextPosition(map2KVTextKey,componentResult,m2ChapterModel);

                                            if(StringUtils.isNotEmpty(map2ValueText)){

                                                if(!map2ValueText.equals("-")){
                                                    if(MapUtils.isNotEmpty(m6MapTable)){
                                                        Set<String> m6Years = m6MapTable.keySet();

                                                        int m6YearSize = m6Years.size();

                                                        int matchCount = 0;

                                                        for(String m6Year:m6Years){

                                                            if(m2Year.equals(m6Year.substring(0,4))){
                                                                logger.info("m2Year：{}，对应合并报表年份m6Year：{}",m2Year,m6Year);
                                                                Map<String, ExtractItem> map6 = m6MapTable.get(m6Year);

                                                                KVText map6KVTextValue = getTableKVTextValue(map6, map2Key);
                                                                KVText map6KVTextKey = getTableKVTextKey(map6, map2Key);

                                                                if(map6KVTextValue!=null){
                                                                    String unit = "万元";
                                                                    ExtractItem extractItem = map6.get(map2Key);
                                                                    if(extractItem!=null){
                                                                        unit = extractItem.getUnit();
                                                                    }
                                                                    logger.info("M-6合并报表单位：{}",unit);

                                                                    String map6ValueText = map6KVTextValue.getText();
                                                                    String map6KeyText = map6KVTextKey.getText();

                                                                    if(StringUtils.isNotEmpty(map6ValueText)){

                                                                        if(!map6ValueText.equals("-")){
                                                                            logger.info("年份：{}，合并报表实际年份：{}，M-6会计科目：{}，数值：{}",m2Year,m6Year,map6KeyText,map6ValueText);

                                                                            map2ValueText = replaceComma(map2ValueText);
                                                                            map6ValueText = replaceComma(map6ValueText);

                                                                            BigDecimal map6ValueTextDecimal = new BigDecimal(map6ValueText);
                                                                            //四舍五入向上保留整数位
                                                                            BigDecimal map6ValueTextDecimalAfter = map6ValueTextDecimal;
                                                                            //向下保留整数位
                                                                            BigDecimal map6ValueTextDecimalDown = map6ValueTextDecimal;

                                                                            if(map2ValueText.contains("亿元")){
                                                                                BigDecimal constant = BigDecimal.valueOf(10000);
                                                                                if(unit.equals("万元")){
                                                                                    constant = BigDecimal.valueOf(10000);
                                                                                }else if(unit.equals("千元")){
                                                                                    constant = BigDecimal.valueOf(100000);
                                                                                }else if(unit.equals("元")){
                                                                                    constant = BigDecimal.valueOf(100000000);
                                                                                }
                                                                                map6ValueTextDecimalAfter = map6ValueTextDecimal.divide(constant, 2, BigDecimal.ROUND_HALF_UP);

                                                                                map6ValueTextDecimalDown = map6ValueTextDecimal.divide(constant, 2, BigDecimal.ROUND_DOWN);

                                                                                logger.info("年份：{}，会计科目：{}，M-6原值：{}，单位转换成亿元后，向上保留：{}，向下保留：{}", m2Year, map2KeyText, map6ValueTextDecimal, map6ValueTextDecimalAfter, map6ValueTextDecimalDown);
                                                                            }else if(map2ValueText.contains("万元")){
                                                                                if(unit.equals("元")){
                                                                                    map6ValueTextDecimalAfter = map6ValueTextDecimal.divide(BigDecimal.valueOf(10000), 2, BigDecimal.ROUND_HALF_UP);

                                                                                    map6ValueTextDecimalDown = map6ValueTextDecimal.divide(BigDecimal.valueOf(10000), 2, BigDecimal.ROUND_DOWN);

                                                                                    logger.info("年份：{}，会计科目：{}，M-6原值：{}，单位转换成万元后，向上保留：{}，向下保留：{}", m2Year, map2KeyText, map6ValueTextDecimal, map6ValueTextDecimalAfter,map6ValueTextDecimalDown);
                                                                                }else if(unit.equals("千元")){
                                                                                    map6ValueTextDecimalAfter = map6ValueTextDecimal.divide(BigDecimal.valueOf(10), 2, BigDecimal.ROUND_HALF_UP);

                                                                                    map6ValueTextDecimalDown = map6ValueTextDecimal.divide(BigDecimal.valueOf(10), 2, BigDecimal.ROUND_DOWN);

                                                                                    logger.info("年份：{}，会计科目：{}，M-6原值：{}，单位转换成万元后，向上保留：{}，向下保留：{}", m2Year, map2KeyText, map6ValueTextDecimal, map6ValueTextDecimalAfter,map6ValueTextDecimalDown);
                                                                                }
                                                                            }

                                                                            if(!map2ValueText.contains(".")){
                                                                                map6ValueTextDecimalAfter = map6ValueTextDecimal.setScale(0, RoundingMode.HALF_UP);

                                                                                map6ValueTextDecimalDown = map6ValueTextDecimalDown.setScale(0, RoundingMode.DOWN);

                                                                                logger.info("年份：{}，会计科目：{}，M-6原值：{}，四舍五入保留整数位：{}，向下保留整数位：{}", m2Year, map2KeyText, map6ValueTextDecimal, map6ValueTextDecimalAfter,map6ValueTextDecimalDown);
                                                                            }

                                                                            BigDecimal map2ValueTextDecimalAfter = new BigDecimal(getAmount(map2ValueText));
                                                                            int num = map6ValueTextDecimalAfter.compareTo(map2ValueTextDecimalAfter);
                                                                            logger.info("开始对比，年份：{}，会计科目：{}，M-2：{}，M-6：{},比较结果：{}", m2Year, map2KeyText, map2ValueTextDecimalAfter, map6ValueTextDecimalAfter, num);

                                                                            if(num != 0){
                                                                                num = map6ValueTextDecimalDown.compareTo(map2ValueTextDecimalAfter);
                                                                                logger.info("开始对比，年份：{}，会计科目：{}，M-2：{}，M-6：{},比较结果：{}", m2Year, map2KeyText, map2ValueTextDecimalAfter, map6ValueTextDecimalAfter, num);
                                                                                if(num==0){
                                                                                    logger.info("年份：{}，会计科目：{}，前后数据一致",m2Year,map2KeyText);
                                                                                    componentResult.setPromptMessage("一致，".concat(m2ItemName).concat("：").concat(map2ValueText).concat("，").concat(m6ItemName).concat("：").concat(map6ValueText).concat(unit));
                                                                                    componentResult.setAnnotationFlag(false);
                                                                                    consistentCount++;
                                                                                }else{
                                                                                    logger.info("年份：{}，会计科目：{}，数据不一致",m2Year,map2KeyText);
                                                                                    componentResult.setPromptMessage("不一致，".concat(m2ItemName).concat("：").concat(map2ValueText).concat("，").concat(m6ItemName).concat("：").concat(map6ValueText).concat(unit));
                                                                                    inconformityCount++;
                                                                                }
                                                                            }else{
                                                                                logger.info("年份：{}，会计科目：{}，前后数据一致",m2Year,map2KeyText);
                                                                                componentResult.setPromptMessage("一致，".concat(m2ItemName).concat("：").concat(map2ValueText).concat("，").concat(m6ItemName).concat("：").concat(map6ValueText).concat(unit));
                                                                                componentResult.setAnnotationFlag(false);
                                                                                consistentCount++;
                                                                            }

                                                                        }else{
                                                                            componentResult.setPromptMessage("无法比较，已识别".concat(m2ItemName).concat("：").concat(map2ValueText).concat("，").concat(m6ItemName).concat("未披露"));
                                                                            unidentification++;
                                                                        }

                                                                    }else{
                                                                        componentResult.setPromptMessage("已识别".concat(m2ItemName).concat("：").concat(map2ValueText).concat("，未识别").concat(m6ItemName).concat("，建议人工核对"));
                                                                        unidentification++;
                                                                    }

                                                                }else{
                                                                    componentResult.setPromptMessage("已识别".concat(m2ItemName).concat("：").concat(map2ValueText).concat("，未识别").concat(m6ItemName).concat("，建议人工核对"));
                                                                    unidentification++;
                                                                }
                                                            }else{
                                                                matchCount++;
                                                            }

                                                            if(m6YearSize==matchCount){
                                                                componentResult.setPromptMessage("已识别".concat(m2ItemName).concat("：").concat(map2ValueText).concat("，未识别").concat(m6ItemName).concat("，建议人工核对"));
                                                                unidentification++;
                                                            }

                                                        }

                                                    }else{
                                                        componentResult.setPromptMessage("已识别".concat(m2ItemName).concat("：").concat(map2ValueText).concat("，未识别").concat(m6ItemName).concat("，建议人工核对"));
                                                        unidentification++;
                                                    }

                                                }else{
                                                    componentResult.setPromptMessage(m2ItemName.concat("未披露数据"));
                                                    unidentification++;
                                                }

                                            }else{
                                                componentResult.setPromptMessage("未识别".concat(m2ItemName).concat("建议人工核对"));
                                                unidentification++;
                                            }

                                            componentResults.add(componentResult);
                                        }

                                    }

                                }

                            }

                    }else{
                        blankCount++;
                    }

                }

                if(blankCount==3){
                    ComponentResult m2ComponentResult = u1004.getComponentResult(getCatalogId(),getChapterId(),ruleName,"抽取财务风险内容处出现的会计科目，与".concat(m6CatalogId).concat("合并财务报表中的会计科目做一致性检查"),"未识别第二章数据，建议人工核对",false,getRegulationId(),m2ChapterModel.getStartPage(),null,"03");
                    ComponentResult m6ComponentResult = u1004.getComponentResult(getCatalogId(),getChapterId(),ruleName,"抽取财务风险内容处出现的会计科目，与".concat(m6CatalogId).concat("合并财务报表中的会计科目做一致性检查"),"",false,getRegulationId(),3,null,"03");

                    if(m6ChapterModel!=null){
                        m6ComponentResult.setPromptMessage("已识别第六章数据，建议人工核对");
                        m6ComponentResult.setPageNum(m6ChapterModel.getStartPage());
                    }else{
                        m6ComponentResult.setPromptMessage("未识别第六章数据，建议人工核对");
                    }

                    componentResults.add(m2ComponentResult);
                    componentResults.add(m6ComponentResult);
                    return componentResults;
                }else{
                    if(componentResults.size()>0){
                        if(inconformityCount>0){
                            for(ComponentResult componentResult : componentResults){
                                componentResult.setExist("02");
                            }
                            return componentResults;
                        }else{
                            if(unidentification>0){
                                for(ComponentResult componentResult : componentResults){
                                    componentResult.setExist("03");
                                }
                                return componentResults;
                            }else{
                                if(consistentCount>0){
                                    for(ComponentResult componentResult : componentResults){
                                        componentResult.setExist("01");
                                        componentResult.setAnnotationFlag(false);
                                    }
                                    return componentResults;
                                }
                            }
                        }
                    }
                }

            }else{
                ComponentResult m2ComponentResult = u1004.getComponentResult(getCatalogId(),getChapterId(),ruleName,"抽取财务风险内容处出现的会计科目，与".concat(m6CatalogId).concat("合并财务报表中的会计科目做一致性检查"),"未识别第二章数据，建议人工核对",false,getRegulationId(),3,null,"03");
                ComponentResult m6ComponentResult = u1004.getComponentResult(getCatalogId(),getChapterId(),ruleName,"抽取财务风险内容处出现的会计科目，与".concat(m6CatalogId).concat("合并财务报表中的会计科目做一致性检查"),"",false,getRegulationId(),3,null,"03");

                if(m6ChapterModel!=null){
                    m6ComponentResult.setPromptMessage("已识别第六章数据，建议人工核对");
                    m6ComponentResult.setPageNum(m6ChapterModel.getStartPage());
                }else{
                    m6ComponentResult.setPromptMessage("未识别第六章数据，建议人工核对");
                }

                componentResults.add(m2ComponentResult);
                componentResults.add(m6ComponentResult);
                return componentResults;
            }

        }catch(Exception e){
            logger.error(e.getMessage(),e);

            if(componentResults.size()==0){
                ComponentResult m2ComponentResult = u1004.getComponentResult(getCatalogId(),getChapterId(),ruleName,"抽取财务风险内容处出现的会计科目，与".concat(m6CatalogId).concat("合并财务报表中的会计科目做一致性检查"),"未识别第二章数据，建议人工核对",false,getRegulationId(),3,null,"03");
                ComponentResult m6ComponentResult = u1004.getComponentResult(getCatalogId(),getChapterId(),ruleName,"抽取财务风险内容处出现的会计科目，与".concat(m6CatalogId).concat("合并财务报表中的会计科目做一致性检查"),"",false,getRegulationId(),3,null,"03");

                if(m2ChapterModel!=null){
                    m2ComponentResult.setPageNum(m2ChapterModel.getStartPage());
                }

                if(m6ChapterModel!=null){
                    m6ComponentResult.setPromptMessage("已识别第六章数据，建议人工核对");
                    m6ComponentResult.setPageNum(m6ChapterModel.getStartPage());
                }else{
                    m6ComponentResult.setPromptMessage("未识别第六章数据，建议人工核对");
                }

                componentResults.add(m2ComponentResult);
                componentResults.add(m6ComponentResult);
                return componentResults;
            }
        }

        return componentResults;
    }
}
